import "core-js/modules/es.error.cause.js";
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
import { BasePlugin } from "../base/index.mjs";
import { loadingContent } from "./content.mjs";
import * as C from "../../i18n/constants.mjs";
export const PLUGIN_KEY = 'loading';
export const PLUGIN_PRIORITY = 350;
export const LOADING_CLASS_NAME = `ht-${PLUGIN_KEY}`;

/**
 * @plugin Loading
 * @class Loading
 *
 * @description
 * The loading plugin provides a loading overlay system for Handsontable using the Dialog plugin.
 * It displays a loading indicator with customizable title, icon, and description.
 *
 * In order to enable the loading mechanism, {@link Options#loading} option must be set to `true`.
 *
 * The plugin provides several configuration options to customize the loading behavior and appearance:
 * - `icon`: Loading icon to display HTML (as string) in svg format (default: `<svg ... />`).
 * - `title`: Loading title to display (default: 'Loading...').
 * - `description`: Loading description to display (default: '').
 *
 * @example
 *
 * ::: only-for javascript
 * ```js
 * // Enable loading plugin with default options
 * loading: true,
 *
 * // Enable loading plugin with custom configuration
 * loading: {
 *   icon: 'A custom loading icon in SVG format',
 *   title: 'Custom loading title',
 *   description: 'Custom loading description',
 * }
 *
 * // Access to loading plugin instance:
 * const loadingPlugin = hot.getPlugin('loading');
 *
 * // Show a loading programmatically:
 * loadingPlugin.show();
 *
 * // Hide the loading programmatically:
 * loadingPlugin.hide();
 *
 * // Check if dialog is visible:
 * const isVisible = loadingPlugin.isVisible();
 * ```
 * :::
 *
 * ::: only-for react
 * ```jsx
 * const MyComponent = () => {
 *   const hotRef = useRef(null);
 *
 *   useEffect(() => {
 *     const hot = hotRef.current.hotInstance;
 *     const loadingPlugin = hot.getPlugin('loading');
 *
 *     loadingPlugin.show();
 *   }, []);
 *
 *   return (
 *     <HotTable
 *       ref={hotRef}
 *       settings={{
 *         data: data,
 *         loading: {
 *           icon: 'A custom loading icon in SVG format',
 *           title: 'Custom loading title',
 *           description: 'Custom loading description',
 *         }
 *       }}
 *     />
 *   );
 * }
 * ```
 * :::
 *
 * ::: only-for angular
 * ```ts
 * hotSettings: Handsontable.GridSettings = {
 *   data: data,
 *   loading: {
 *     icon: 'A custom loading icon in SVG format',
 *     title: 'Custom loading title',
 *     description: 'Custom loading description',
 *   }
 * }
 * ```
 *
 * ```html
 * <hot-table
 *   [settings]="hotSettings">
 * </hot-table>
 * ```
 * :::
 */
var _dialogPlugin = /*#__PURE__*/new WeakMap();
var _Loading_brand = /*#__PURE__*/new WeakSet();
export class Loading extends BasePlugin {
  constructor() {
    super(...arguments);
    /**
     * Handle dialog focus event.
     */
    _classPrivateMethodInitSpec(this, _Loading_brand);
    /**
     * Dialog instance reference.
     *
     * @type {Dialog|null}
     */
    _classPrivateFieldInitSpec(this, _dialogPlugin, null);
  }
  static get PLUGIN_KEY() {
    return PLUGIN_KEY;
  }
  static get PLUGIN_PRIORITY() {
    return PLUGIN_PRIORITY;
  }
  static get DEFAULT_SETTINGS() {
    return {
      // eslint-disable-next-line max-len
      icon: `<svg class="${LOADING_CLASS_NAME}__icon-svg" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16"><path stroke="currentColor" stroke-width="2" d="M15 8a7 7 0 1 1-3.5-6.062"></path></svg>`,
      title: undefined,
      description: ''
    };
  }
  static get SETTINGS_VALIDATORS() {
    return {
      icon: value => typeof value === 'string',
      title: value => typeof value === 'string',
      description: value => typeof value === 'string'
    };
  }
  /**
   * Check if the plugin is enabled in the handsontable settings.
   *
   * @returns {boolean}
   */
  isEnabled() {
    return !!this.hot.getSettings()[PLUGIN_KEY];
  }

  /**
   * Enable plugin for this Handsontable instance.
   */
  enablePlugin() {
    if (this.enabled) {
      return;
    }
    if (_classPrivateFieldGet(_dialogPlugin, this) === null) {
      var _classPrivateFieldGet2;
      _classPrivateFieldSet(_dialogPlugin, this, this.hot.getPlugin('dialog'));
      if (!((_classPrivateFieldGet2 = _classPrivateFieldGet(_dialogPlugin, this)) !== null && _classPrivateFieldGet2 !== void 0 && _classPrivateFieldGet2.isEnabled())) {
        this.hot.getSettings().dialog = true;
      }
      this.hot.addHook('afterDialogFocus', () => _assertClassBrand(_Loading_brand, this, _onAfterDialogFocus).call(this));
    }
    super.enablePlugin();
  }

  /**
   * Update plugin state after Handsontable settings update.
   */
  updatePlugin() {
    this.disablePlugin();
    this.enablePlugin();
    super.updatePlugin();
  }

  /**
   * Disable plugin for this Handsontable instance.
   */
  disablePlugin() {
    this.hide();
    super.disablePlugin();
  }

  /**
   * Check if loading dialog is currently visible.
   *
   * @returns {boolean}
   */
  isVisible() {
    var _classPrivateFieldGet3, _classPrivateFieldGet4;
    return (_classPrivateFieldGet3 = (_classPrivateFieldGet4 = _classPrivateFieldGet(_dialogPlugin, this)) === null || _classPrivateFieldGet4 === void 0 ? void 0 : _classPrivateFieldGet4.isVisible()) !== null && _classPrivateFieldGet3 !== void 0 ? _classPrivateFieldGet3 : false;
  }

  /**
   * Show loading dialog with optional custom options.
   *
   * @param {object} options Custom loading options.
   * @param {string} options.icon Custom loading icon.
   * @param {string} options.title Custom loading title.
   * @param {string} options.description Custom loading description.
   */
  show() {
    var _classPrivateFieldGet5;
    let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    if (!this.isEnabled() || !_classPrivateFieldGet(_dialogPlugin, this) || !((_classPrivateFieldGet5 = _classPrivateFieldGet(_dialogPlugin, this)) !== null && _classPrivateFieldGet5 !== void 0 && _classPrivateFieldGet5.isEnabled())) {
      return;
    }
    if (this.isVisible()) {
      this.update(options);
      return;
    }
    const shouldProceed = this.hot.runHooks('beforeLoadingShow');
    if (shouldProceed === false) {
      return;
    }
    this.update(options);
    _classPrivateFieldGet(_dialogPlugin, this).show();
    this.hot.runHooks('afterLoadingShow');
  }

  /**
   * Hide loading dialog.
   */
  hide() {
    var _classPrivateFieldGet6;
    if (!_classPrivateFieldGet(_dialogPlugin, this) || !((_classPrivateFieldGet6 = _classPrivateFieldGet(_dialogPlugin, this)) !== null && _classPrivateFieldGet6 !== void 0 && _classPrivateFieldGet6.isEnabled()) || !this.isVisible()) {
      return;
    }
    const shouldProceed = this.hot.runHooks('beforeLoadingHide');
    if (shouldProceed === false) {
      return;
    }
    _classPrivateFieldGet(_dialogPlugin, this).hide();
    this.hot.runHooks('afterLoadingHide');
  }

  /**
   * Update loading description without hiding/showing the dialog.
   *
   * @param {object} options Custom loading options.
   * @param {string} options.icon Custom loading icon.
   * @param {string} options.title Custom loading title.
   * @param {string} options.description Custom loading description.
   */
  update(options) {
    var _classPrivateFieldGet7, _this$getSetting;
    if (!this.isEnabled() || !_classPrivateFieldGet(_dialogPlugin, this) || !((_classPrivateFieldGet7 = _classPrivateFieldGet(_dialogPlugin, this)) !== null && _classPrivateFieldGet7 !== void 0 && _classPrivateFieldGet7.isEnabled())) {
      return;
    }
    this.updatePluginSettings(options);
    const id = this.hot.guid;
    const icon = this.getSetting('icon');
    const title = (_this$getSetting = this.getSetting('title')) !== null && _this$getSetting !== void 0 ? _this$getSetting : this.hot.getTranslatedPhrase(C.LOADING_TITLE);
    const description = this.getSetting('description');
    const content = loadingContent({
      id,
      icon,
      title,
      description
    });
    _classPrivateFieldGet(_dialogPlugin, this).update({
      content,
      customClassName: LOADING_CLASS_NAME,
      background: this.hot.countSourceRows() === 0 ? 'solid' : 'semi-transparent',
      a11y: {
        role: 'alertdialog',
        ariaLabelledby: `${id}-${PLUGIN_KEY}-title`,
        ariaDescribedby: description ? `${id}-${PLUGIN_KEY}-description` : undefined
      }
    });
  }
  /**
   * Destroy plugin instance.
   */
  destroy() {
    _classPrivateFieldSet(_dialogPlugin, this, null);
    super.destroy();
  }
}
function _onAfterDialogFocus() {
  _classPrivateFieldGet(_dialogPlugin, this).focus();
}